﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Vds2465Telegrams;

namespace Vds2465Parser
{
    internal static class GenParse_UserData_10_Query
    {
        #region private constants

        private const int NrOfBytes = 4;
        private const int NrOfBytesExtended = 7;

        #endregion private constants

        #region internal methods

        internal static byte[] GenerateBytes(UserData userData)
        {
            byte[] userDataBytes = null;

            if (userData is UserData_10_Query)
            {
                UserData_10_Query userData10 = userData as UserData_10_Query;
                if (userData10.SimpleVariant)
                {
                    userDataBytes = new byte[NrOfBytes];
                    userDataBytes[0] = NrOfBytes - GenParse_UserData.HeaderLength;	// user data length
                    userDataBytes[1] = UserData.UserData10Query;
                    userDataBytes[2] = userData10.Device;
                    userDataBytes[3] = userData10.QueryType;
                }
                else
                {
                    // extended: general, state query, test timer
                    userDataBytes = new byte[NrOfBytesExtended];
                    userDataBytes[0] = NrOfBytesExtended - GenParse_UserData.HeaderLength;	// user data length
                    userDataBytes[1] = UserData.UserData10Query;
                    userDataBytes[2] = userData10.Device;
                    userDataBytes[3] = userData10.Address;
                    userDataBytes[4] = userData10.AddressAddOn;
                    userDataBytes[5] = userData10.AddressExtension;
                    userDataBytes[6] = userData10.QueryType;
                }
            }
            else
            {
                // TODO handle error
            }

            return userDataBytes;
        }

        internal static bool ParseBytes(byte[] userDataBytes, out UserData userData10Query, out int consumedBytes)
        {
            userData10Query = null;
            consumedBytes = 0;

            if (userDataBytes.Length >= NrOfBytes)
            {
                // first byte
                if (
                    (userDataBytes[0] == NrOfBytes - GenParse_UserData.HeaderLength)
                    || (userDataBytes[0] == NrOfBytesExtended - GenParse_UserData.HeaderLength)
                    )
                {
                    if (userDataBytes[1] == UserData.UserData10Query)
                    {
                        if (userDataBytes[0] == NrOfBytesExtended - GenParse_UserData.HeaderLength)
                        {
                            byte device = userDataBytes[2];
                            byte address = userDataBytes[3];
                            byte addressAddOn = userDataBytes[4];                            
                            byte addressExtension = userDataBytes[5];                           
                            byte queryType = userDataBytes[6];

                            CheckAddressExtensionValue(queryType, addressExtension);

                            userData10Query = new UserData_10_Query(queryType, device, address, addressAddOn, addressExtension);
                            consumedBytes = NrOfBytesExtended;
                            return true;
                        }
                        else
                        {
                            // simple variant                            
                            byte device = userDataBytes[2];
                            byte queryType = userDataBytes[3];

                            userData10Query = new UserData_10_Query(queryType, device);
                            consumedBytes = NrOfBytes;
                            return true;
                        }
                    }

                    // TODO handle error: wrong value for the data type
                    return false;
                }

                // TODO handle error (wrong value in first byte the length)
                return false;
            }

            // TODO handle error (not enough bytes)
            return false;
        }

        #endregion internal methods

        #region private methods

        private static void CheckAddressExtensionValue(byte queryType, byte addressExtension)
        {
            if (        (queryType == UserData.UserData20State)
                    ||  (queryType == UserData.UserData24BlockState)                    
                )
            {
                if 
                    (
                            (addressExtension != (byte) eAddressExtension_1.Input)
                    &&      (addressExtension != (byte) eAddressExtension_1.Output)
                    &&      (addressExtension != (byte) eAddressExtension_1.Disruption)
                    )
                {
                    // TODO handle error
                }
            }
            else if (queryType == UserData.UserData41TestConfirm)
            {
                if
                    (
                            (addressExtension != (byte)eAddressExtension_2.TestMessageInterval)
                        &&  (addressExtension != (byte)eAddressExtension_2.TimeToNextTestMessage)
                    )
                {
                    // TODO handle error
                }
            }
        }

        #endregion private methods
    }
}
